import { decode } from 'jsonwebtoken';
import { history, request as sendRequest } from '@umijs/max';
import { Dropdown, Space, Avatar } from 'antd';
import Icon from '@ant-design/icons';
import * as icons from '@ant-design/icons';
/**
 * app.tsx是一个非常特殊的文件，用来运行时配置项目
 * 获取初始化的状态
 * getInitialState 是用来返回初始状态的
 */
export async function getInitialState() {
    const initialState = {
        currentUser: null //代表当前的用户
    }
    //每当页面刷新的时候都会执行此方法，我们可以在这里获取本地储存的tokens并重新放置到仓库中
    const tokens = localStorage.getItem('tokens');
    if (tokens) {
        try {
            const { access_token } = JSON.parse(tokens);
            const { currentUser } = decode(access_token);
            //解码token，获取里面的用户，并且赋值给initialState.currentUser
            initialState.currentUser = currentUser;
        } catch (error) {
            console.error(error);
        }
    }
    return initialState;
}
const WHITE_LIST = ['/api/signin'];
//导出request的配置
export let request = {
    timeout: 3000,//配置超时时间
    headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        credential: 'include'//允许跨域请求的时候发送cookie
    },
    requestInterceptors: [//配置请求拦截器
        (url, options) => {
            //有可能请求接口的时候token过期了，这个时候，我就就可以尝试刷新token,获取最新的token
            //然后再次发送请求
            const tokens = localStorage.getItem('tokens');
            if (tokens) {
                try {
                    const { access_token } = JSON.parse(tokens);
                    //把访问的access_token放在请求头里发送给服务器用来让服务识别当前的用户的身份
                    options.headers.authorization = `Bearer ${access_token}`
                } catch (error) {
                    console.error(error)
                }
            }
            return { url, options };
        },
        (url, options) => {
           //此拦截器用来判断此用户是否有某个接口的权限
           //如果此请求不需要鉴权，则直接放过
            if(WHITE_LIST.includes(url)){
                return { url, options };
            }
            const tokens = localStorage.getItem('tokens');
            if (tokens) {
                try {
                    const { access_token } = JSON.parse(tokens);
                    const { currentUser } = decode(access_token);
                    const {apis} = currentUser;
                    const hasPermission = apis.some(api=>{
                        //判断当前的请求中，方法名和路径是否在授权的API列表中
                        return api.method.toLowerCase() === options.method.toLowerCase()
                        && new RegExp(api.path).test(url)
                    });
                    if(hasPermission){
                        return { url, options };
                    }else{
                        return;
                    }
                } catch (error) {
                    console.error(error)
                }
            }

        }
    ],
    responseInterceptors: [//响应拦截器，返回响应中的data属性
        (response) => response.data
    ]
}
const formatMenuItems = (menus) => {
    return menus.map(({icon,routes,...rest}) => {
        return {
            ...rest,
            icon:icon&&<Icon component={icons[icon]}/>,
            routes:routes&&formatMenuItems(routes)
        }
    })
}
//运行时配置布局
export const layout = ({ initialState, setInitialState }) => {
    return {
        title: "UMI权限",
        //当路径发生修改时执行此钩子
        onPageChange(location) {
            const { currentUser } = initialState;
            //如果仓库中的当前用户不存在并且当前的路径不是登录页面
            if (!currentUser && location.pathname !== '/signin') {
                //说明当前用户没有权限访问，跳回登录页登录
                history.push('/signin');
            }
        },
        actionsRender: () => {
            const { currentUser } = initialState;
            console.log('currentUser',currentUser);
            if (!currentUser) return null;
            const items = [
                {
                    key: 'logout',
                    label: (
                        <a
                            onClick={() => {
                                setInitialState({ currentUser: null });//清空仓库中的用户信息
                                localStorage.removeItem('tokens');//清除token
                                history.push('/signin');//跳到登录页
                            }}
                        >
                            退出
                        </a>
                    )
                }
            ]
            return [
                <Dropdown menu={{ items }}>
                    <Space>
                        <Avatar size={32} src={currentUser.avatar} />
                        <span>{currentUser.username}</span>
                    </Space>
                </Dropdown>
            ]
        },
        menu: {
            locale: false,//关闭菜单的国际化
            request: async (params, defaultMenuData) => {
                //请求/api/menus,服务器会根据当前用户的角色，获取对应角色的菜单，返回有权限的菜单
                const { menus } = await sendRequest('/api/menus');
                //把老的菜单配置和新的返回的动态菜单配置合并在一起返回组成菜单
                return [...defaultMenuData, ...formatMenuItems(menus)];
            }
        }
    }
}